/**
 * 表单渲染
 */
;
(function(global, factory) {
	"use strict";
	if(typeof define === "function" && define.amd) {
		define(['jquery', 'util/commonUtil', 'bootstrapFormHelper', "util/formElementManager", "util/formValidator"], function(a, b, c, d, e){
			return factory(global, a, b, c, d, e);
		});
	} else {
		factory(global, $);
	}
})(typeof window !== "undefined" ? window : this, function(window, $, commonUtil, bootstrapFormHelper, formElementManager, formValidator) {
	
	if (typeof $ === 'undefined') {
		throw new Error('requires jQuery')
	}
	
	/**
	 * 新增模型数据
	 * @param {Object} ghost
	 */
	let privateInsertModelData = function(ghost) {
		return new Promise(function (resolve, reject) {
			let url = APP_CONFIG.domain.cmdb + "/model/insertModel/" + modelType + "/" + modelId ;
			let handleBack = (data) => {
		        if(data?.code == 100) {
		        	ghost.data("dataposted", true);
		        	commonUtil.info('保存成功');
		        	resolve();
		        } else {
		        	commonUtil.error('数据保存失败');
		        }
		    }
			commonUtil.mask();
			$.ajax({
					"url": url, "type": "post", "dataType": "json", "data": formDataSerialize(), 
					"success": function(data) {
						console.log(data);
						handleBack(data);
					},
					"error": function(data) {
						console.log(data);
						handleBack(data);
					},
					"complete": function() {
						commonUtil.unmask();
					}
			});	
		});
	}
	/**
	 * 修改模型数据
	 */
	let privateUpdateModelData = function(ghost) {
		return new Promise(function (resolve, reject) {
			let url = APP_CONFIG.domain.cmdb + "/model/updateModel/" + modelType + "/" + modelId ;
			let handleBack = (data) => {
		        if(data?.code == 100) {
		        	ghost.data("dataposted", true);
		        	commonUtil.info('保存成功');
		        	resolve();
		        } else {
		        	commonUtil.error('数据保存失败');
		        }
		    }
			commonUtil.mask();
			$.ajax({
					"url": url, "type": "post", "dataType": "json", "data": formDataSerialize(), 
					"success": function(data) {
						console.log(data);
						handleBack(data);
					},
					"error": function(data) {
						console.log(data);
						handleBack(data);
					},
					"complete": function() {
						commonUtil.unmask();
					}
			});	
		});
	}
	/**
	 * 加载模型数据
	 */
	let privateLoadModelData = function() {
		return new Promise(function (resolve, reject) {
	        if(dataId) {
	        	let tmpId = dataId;
		        let handleBack = (data) => {
		        	if(data?.code == 100) {
		        		privateFillingModelForm(data?.result);
		        		resolve();
		        	} else {
		        		commonUtil.error('加载数据失败');
		        	}
		        }
		        let url = APP_CONFIG.domain.cmdb + "/model/selectModelById/" + modelType + "/" + modelId ;
				commonUtil.mask();
				$.ajax({
					"url": url, "type": "post", "dataType": "json", "data": {'id': tmpId }, 
					"success": function(data) {
						console.log(data);
						handleBack(data);
					},
					"error": function(data) {
						console.log(data);
						handleBack(data);
					},
					"complete": function() {
						commonUtil.unmask();
					}
				});	
	        } else {
	        	resolve();
	        }
			
	    });
	}
	
	/**
	 * 表单序列化
	 * 需要从组件定义的取值方法上取值
	 * @returns 表单序列化字符串
	 */
	let formDataSerialize = () => {
		//let str = $("#formv2021").serialize();
		//return str;
		let str = 'id='+dataId+"&config_model_id="+modelId+"&model_type="+modelType;
		$("#formv2021 [data-property-code]").each(function(){
			let dom = $(this);
			let k = dom.attr("data-property-code");
			let v = '';
			let componentIns = dom.data("componentInstance");
			if( componentIns ){
				if(componentIns.readonly()) {
					return true;
				}
				v = componentIns.val();
			} else {
				//k = dom.attr("data-property-code");
				let inputDom = dom.find("[name]");
				if(inputDom.readonly) {
					return true;
				}
				v = inputDom.val();
			}
			v = v??"";
			str += '&' + k + '=' + encodeURIComponent(v);
		});
		return str;
	}

	/**
	 * 渲染数据
	 */
	let privateFillingModelForm = (dataObject) => {
		console.log(dataObject);
		for(let k in dataObject) {
			let v = dataObject[k];
			let dom = $("[data-property-code='" + k + "']");
			//let componentName = dom.attr("data-conp-name");
			let componentIns = dom.data("componentInstance");
			//if(componentName && typeof window[componentName] !== "undefined"){
			//let domId = dom.children("[id]").first().attr("id");
			if( componentIns ){
				componentIns.val(v);
			} else {
				//console.log('属性编码：' + k + '普通方法设值');
				$("[name='" + k + "']").val(v);
			}
		}
	}
	let init = () => {
		$(document).on("click", "#formv2021-btn-calcel", function(evt){
			console.log("取消");
			commonUtil.toast("取消");
		});
		
	}
	
	let bindBtnEvents = () => {
		$(document).on("click", "#formv2021-btn-save", function(evt){
			console.log("提交数据");
			console.log(this);
			let ghost = $(this);
			if(ghost.data("dataposted")) {
				commonUtil.warn("数据已提交，请勿重复提交数据");
				return false;
			}
			if($.validAll()) {
				privateInsertModelData(ghost);
			}
		}).on("click", "#formv2021-btn-update", function(evt){
			console.log("更新数据");
			let ghost = $(this);
			if(ghost.data("dataposted")) {
				commonUtil.warn("数据已提交，请勿重复提交数据");
				return false;
			}
			if($.validAll()) {
				privateUpdateModelData(ghost);
			}
		});
		
	}
	
	let formWrapper = () => $("#form-wrapper");
	/**
	 * 根据一生成的html元素渲染页面
	 */
	let renderByHtml = function(html) {
		if(html) {
			let input_config_model_id = '<input type="hidden" id="config_model_id" name="config_model_id" value="' + modelId + '" />';//modelId
			let input_model_type      = '<input type="hidden" id="model_type" name="model_type" value="' + modelType + '" />';//modelType
			let input_data_id         = '<input type="hidden" id="id" name="id" />';//数据实例id
			//let formhtml = '<form id="formv2021" role="form">' + input_config_model_id + input_model_type + input_data_id + '</form>';
			let formhtml = '<form id="formv2021" role="form"></form>';
			
			formWrapper().html(formhtml);
			$("#formv2021").append(input_config_model_id).append(input_model_type).append(input_data_id).append(html);
		}
		//console.log(this);
		
		$("#formv2021 .draggable-element").each(function() {
			let componentIns = renderLayoutElement($(this));
			if(componentIns) {
				try{
					initValidator(componentIns);
				} catch (e) {
					console.log("初始化验证失败！", e);
				}
				
				try{
					let eventsObj = componentIns.events();
					let target = componentIns.inputDom() ?? componentIns.$dom;
					if(typeof( eventsObj ) === 'object' && !$.isEmptyObject(eventsObj)) {
						console.log(eventsObj);
						for(let _k in eventsObj) {
							target.on(_k, {"eventSourceData": eventsObj[_k]}, function(evt){
								let tmpFunc = new Function(evt.data.eventSourceData);
								return tmpFunc(evt);
							});
						}
					}
				}catch(e){
					console.log("初始化自定义事件失败！", e);
				}
				
			}
		});
		
		//return this;
	}
	
	let renderLayoutElement = (helper) => {
		let tmpInstance = helper.data("componentInstance");
		//let componentName = helper.attr('data-conp-name');
		//if(componentName) {
		if(typeof tmpInstance !== 'object') {
			// 从页面已存在的html生成对象实例
			let domId = helper.children("[id]").first().attr("id");
			let componentName = helper.attr('data-conp-name');
			tmpInstance = new window[componentName](domId);
			helper.data("componentInstance", tmpInstance);
		}
		let propertyId = helper.attr("data-property-id");
		if(propertyId) {
			let property = formElementManager.getModelProperty(propertyId);
			tmpInstance.propertyId = propertyId;//setter
			tmpInstance.property = property;//setter
		}
		//console.log(tmpInstance);
		return tmpInstance;
	}
	
	let initValidator = (componentIns) => {
		let dom = $(componentIns.dom);
		let inputDom = componentIns.inputDom();
		let validRequired = dom.attr("data-validate-required");
		if(validRequired == "true") {
			if(inputDom) {
				inputDom.addValide("required");
			}
		}
		let validConf = componentIns.validateConfig();
		//console.log(validConf);
		{
			let valiLenMin = validConf.minlength??"";
			let valiLenMax = validConf.maxlength??"";
			if(valiLenMin || valiLenMax) {
				inputDom.addValide("length[" + valiLenMin + "-" + valiLenMax + "]");
			}
		}
		
		{
			let rule = validConf?.rule;
			if(rule) {
				let rules = rule.split(",");
				for(let i in rules) {
					inputDom.addValide(rules[i]);
				}
			}
		}
		
		
		{
			let reg = validConf?.reg;
			let regtitle = validConf?.regtitle ?? "正则验证未通过";
			
			if(reg) {
				let prefix = "data" + '-vali';
				inputDom.attr(prefix + "-" + "reg", reg);
				inputDom.attr(prefix + "-" + "regtitle", regtitle);
			}
		}
		formValidator.init();
	}
	
	
	/**
	 * 生成页面按钮
	 * @param {Object} type
	 */
	let renderButton = function(type) {
		$(".form-btn-wrapper").remove();
		let btnWrapper= '<div class="form-btn-wrapper"></div>';
		let btnAdd    = '<button type="button" id="formv2021-btn-save" class="btn btn-success">提交</button>';
		let btnEdit   = '<button type="button" id="formv2021-btn-update" class="btn btn-success">保存</button>';
		let btnCancel = '<button type="button" id="formv2021-btn-calcel" class="btn btn-default">取消</button>';
		formWrapper().after(btnWrapper);
		
		// 不能根据页面类型判断，而应该根据是否有dataId来判断
		if(dataId) {
			$(".form-btn-wrapper").append(btnEdit);
		} else {
			$(".form-btn-wrapper").append(btnAdd);
		}
		/**
		if(type == 'add') {
			$(".form-btn-wrapper").append(btnAdd);
		}
		if(type == 'edit') {
			$(".form-btn-wrapper").append(btnEdit);
		}
		*/
		$(".form-btn-wrapper").append(btnCancel);
		//return this;
	}
	
	/**
	 * 渲染表单页面入口
	 * @param {Object} html 页面内容
	 * //@param {Object} type 页面类型
	 */
	let rendPage = function( html ) {
		
		//调用初始化
		init();
		
		//写页面内容
		renderByHtml(html);
		
		//如果有dataId参数，加载模型数据
		privateLoadModelData().then(function(){
			//添加页面按钮
			renderButton();
			
			//绑定按钮事件
			bindBtnEvents();
		} );
		
		
	}
	
	let formView = {
		"init": init,
		"rendPage": rendPage
	};
	
	return formView;
	
});
